﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CXJ.Libiary;

namespace CXJ.AutoCode
{
    public partial class MainForm : Form
    {
        private IList<string> _CheckTableName = new List<string>();

        public MainForm()
        {
            InitializeComponent();

            InitDataGridView();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            InitDBTable();
        }

        private void InitDBTable()
        {
            string strSelectTable = "SELECT id,name,rtrim(ltrim(xtype)) xtype   FROM sysobjects where (xtype='U') and status>=0 order by name ";
            DataSet pDataSet = CXJ.Libiary.DBManager.Instance.GetDataSet(strSelectTable);
            if (pDataSet != null && pDataSet.Tables != null && pDataSet.Tables[0] != null)
            {
                BindListView(pDataSet.Tables[0]);
            }
        }
        void BindListView(DataTable dataTable)
        {
            if (dataTable == null) return;

            listView1.Items.Clear();
            int i = 1;

            foreach (DataRow itemDataRow in dataTable.Rows)
            {
                ListViewItem item = new ListViewItem();
                item.Text = (i++).ToString();
                item.SubItems.Add(itemDataRow[1].ToString());
                if (itemDataRow[2].ToString() == "U" || itemDataRow[2].ToString() == "TABLE")
                {
                    item.SubItems.Add("表");
                }
                else
                {
                    item.SubItems.Add("视图");
                }

                listView1.Items.Add(item);
            }

        }

        private void GetCheckTable()
        {
            foreach (ListViewItem item in listView1.Items)
            {
                if (item.Checked)
                {
                    _CheckTableName.Add(item.SubItems[1].Text);
                }
            }
        }

        private void button_create_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(textBox_namespace.Text.Trim()))
            {
                MessageBox.Show("Model NameSpace Can't for Empty ！");
                textBox_namespace.Focus();
                return;
            }
            if (string.IsNullOrEmpty(textBox_path.Text))
            {
                MessageBox.Show("Code rebulid path Can't for Empty ！");
                textBox_path.Focus();
                return;
            }
            DataTable pDataTable = dataGridView.DataSource as DataTable;
            BulidModelCS(pDataTable);
        }

        private void button_next_Click(object sender, EventArgs e)
        {
            GetCheckTable();
            if (_CheckTableName.Count < 1)
            {
                MessageBox.Show("没有选择要生成的表,请选择要生成的表!");
                return;
            }
            this.tabControl1.SelectedTab = tabPage_tableAttribue;
            SelectTableAttribue(_CheckTableName);
        }

        private void button_refresh_Click(object sender, EventArgs e)
        {
            InitDBTable();
        }

        private void SelectTableAttribue(IList<string> tableNames)
        {
            if (tableNames.Count < 1) return;
            string strSQL = "select b.name as tableName,a.name as columnName,c.name as dataType,a.length,'false' as IsPK,'true' AS IsInsert,'true' as IsUpdate,'false' as IsDelete,'true' as IsSelect from syscolumns as a inner join sysobjects as b on a.id=b.id inner join systypes as c  on a.xtype=c.xusertype where #CONDITION# order by b.name ";
            string strCondition = " b.name IN (";
            foreach (string item in tableNames)
            {
                strCondition += "'" + item + "',";
            }
            strCondition = strCondition.Remove(strCondition.Length - 1, 1);
            strCondition += ") ";
            strSQL = strSQL.Replace("#CONDITION#", strCondition);
            DataSet pDataSet = CXJ.Libiary.DBManager.Instance.GetDataSet(strSQL);
            if (pDataSet == null) return;
            dataGridView.DataSource = pDataSet.Tables[0];

        }

        private void InitDataGridView()
        {
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit();

            this.dataGridView.Columns.Clear();

            this.dataGridView.Columns.Add(CreateTextBoxColumn("tableName", 150));
            this.dataGridView.Columns.Add(CreateTextBoxColumn("columnName"));
            this.dataGridView.Columns.Add(CreateTextBoxColumn("dataType"));
            this.dataGridView.Columns.Add(CreateTextBoxColumn("length", 60));

            this.dataGridView.Columns.Add(CreateCheckBoxColumn("IsPK"));
            this.dataGridView.Columns.Add(CreateCheckBoxColumn("IsInsert"));
            this.dataGridView.Columns.Add(CreateCheckBoxColumn("IsUpdate"));
            this.dataGridView.Columns.Add(CreateCheckBoxColumn("IsDelete"));
            this.dataGridView.Columns.Add(CreateCheckBoxColumn("IsSelect"));

            this.dataGridView.AutoGenerateColumns = false;
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).EndInit();

        }
        private DataGridViewTextBoxColumn CreateTextBoxColumn(string name)
        {
            return this.CreateTextBoxColumn(name, 100);
        }
        private DataGridViewTextBoxColumn CreateTextBoxColumn(string name, int length)
        {
            DataGridViewTextBoxColumn tempTextBox = new DataGridViewTextBoxColumn();
            tempTextBox.Name = name;
            tempTextBox.HeaderText = name;
            tempTextBox.DataPropertyName = name;
            tempTextBox.Width = length;
            tempTextBox.ReadOnly = true;
            return tempTextBox;
        }
        private DataGridViewCheckBoxColumn CreateCheckBoxColumn(string name)
        {
            DataGridViewCheckBoxColumn tempCheckBox = new DataGridViewCheckBoxColumn(false);
            tempCheckBox.Name = name;
            tempCheckBox.HeaderText = name;
            tempCheckBox.DataPropertyName = name;
            tempCheckBox.Width = 60;
            tempCheckBox.IndeterminateValue = false;
            tempCheckBox.ValueType = typeof(Boolean);
            return tempCheckBox;
        }


        private void BulidModelCS(DataTable table)
        {
            if (table == null) return;

            foreach (string item in _CheckTableName)
            {
                DataRow[] drs = table.Select(" tableName='" + item + "' ");
                CreateFile(drs, item);
            }
        }

        private void CreateFile(DataRow[] drs, string className)
        {
            if (drs == null) return;
            string newLine = System.Environment.NewLine;
            StringBuilder sb = new StringBuilder();
            sb.Append("using System;" + newLine);
            sb.Append("using System.Data;" + newLine);
            sb.Append("using CXJ.Libiary;" + newLine);
            sb.Append(newLine);
            sb.Append("namespace CXJ.Model" + newLine);
            sb.Append("{" + newLine);
            sb.Append("\tpublic class " + className + "Entity : BaseEntity" + newLine);
            sb.Append("\t{" + newLine);

            sb.Append("\t\tpublic override string TABLE_NAME { get { return \"" + className + "\"; } }" + newLine);
            bool ishasPK = false;

            foreach (DataRow item in drs)
            {
                string pk = item["columnName"].ToString();
                if (item["IsPK"].ToBool() && !ishasPK)
                {
                    sb.Append("\t\tpublic override string PK { get { return \"" + pk + "\"; } }" + newLine);
                    sb.Append("\t\tpublic override object PK_VALUE" + newLine);
                    sb.Append("\t\t{" + newLine);
                    sb.Append("\t\t\tget { return " + pk + "; }" + newLine);
                    sb.Append("\t\t\tset { " + pk + " = value.ToString(); }" + newLine);
                    sb.Append("\t\t}" + newLine);
                    ishasPK = true;
                }
                sb.Append("\t\t[DBColumnAttribue(true, " + item["IsInsert"].ToBool().ToBoolString() + ", " + item["IsDelete"].ToBool().ToBoolString() + ", " + item["IsUpdate"].ToBool().ToBoolString() + ", " + item["IsSelect"].ToBool().ToBoolString() + ", DbType." + GetDbTypeName(item["dataType"].ToString().ToLower()) + ")]" + newLine);
                sb.Append("\t\tpublic string " + pk + " { get; set; }" + newLine);
                sb.Append(newLine);

            }

            sb.Append("\t}" + newLine);
            sb.Append("}" + newLine);

            System.IO.Stream pStream = new System.IO.FileStream(System.IO.Path.Combine(textBox_path.Text, className + ".cs"), System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite, System.IO.FileShare.Write);
            byte[] buffer = new byte[sb.Length];
            buffer = System.Text.Encoding.Default.GetBytes(sb.ToString());
            pStream.Write(buffer, 0, buffer.Length);
            pStream.Flush();
            pStream.Close();
        }

        private void button_file_Click(object sender, EventArgs e)
        {
            using (FolderBrowserDialog pFolderBrowserDialog = new FolderBrowserDialog())
            {
                pFolderBrowserDialog.Description = "选择要保存生成代码的路径";
                if (pFolderBrowserDialog.ShowDialog(this) == DialogResult.OK)
                {
                    textBox_path.Text = pFolderBrowserDialog.SelectedPath;
                }
            }
        }

        public string GetDbTypeName(string name)
        {
            DbType tempType = DbType.AnsiString;
            switch (name)
            {
                case "int":
                case "smallint":
                case "tinyint":
                    tempType = DbType.Int32;
                    break;
                case "nchar":
                    tempType = DbType.AnsiString;
                    break;
                case "datetime":
                case "smalldatetime":
                    tempType = DbType.DateTime;
                    break;
                case "money":
                case "float":
                    tempType = DbType.Double;
                    break;
                default:
                    tempType = DbType.AnsiString;
                    break;
            }
            return tempType.ToString();
        }
    }
    public static class Expend
    {
        public static bool ToBool(this object obj)
        {
            if (obj == null) return false;
            if (obj.Equals(DBNull.Value)) return false;
            try
            {
                return obj.ToString().ToLower() == "true";
            }
            catch { return false; }
        }

        public static string ToBoolString(this object obj)
        {
            return obj.ToString().ToLower();
        }
    }

}
